export default class OSSUpload{
    constructor(options) {
        Object.assign(this, (options || {}), {
            serverUrl: 'https://imotest.xiaosaas.com/rest/opp/file/upload/policy/x2',
            timeout: 3600 * 1000,
            expireTime: 150,//失效时长 S
        })
    }
    XMLHttpRequest(){
        let xmlhttp = null;
        if (window.XMLHttpRequest) {
            xmlhttp = new window.XMLHttpRequest();
        } else if (window.ActiveXObject) {
            xmlhttp = new window.ActiveXObject("Microsoft.XMLHTTP");
        }
        return xmlhttp
    }
    upload(file){
        return new Promise(function (resolve, reject){
            let _this = this;
            if(typeof file === 'object' && file.length){
                if(file.length  ===  1){
                    file = file[0]
                }else{
                    let files = []
                    for(let i = 0; i < file.length; i++){
                        files.push(file[i])
                    }
                    file = files;
                }
            }
            if(Array.isArray(file)){
                this.isMultiple = true;
                this.fileList = file;
                let len = file.length;
                let fileIndex = this.fileIndex = 0;
                let successFile = [];
                let errorFile = [];
                function up(){
                    _this.uploadOne(file[fileIndex]).then(function (res){
                        successFile.push(res)
                    }).catch(function (err){
                        errorFile.push(err)
                    }).finally(function (){
                        fileIndex++;
                        _this.fileIndex = fileIndex;
                        if(fileIndex < len){
                            up();
                        }else{
                            if(errorFile.length === len){
                                reject(errorFile)
                            }else{
                                resolve({success: successFile, error: errorFile})
                            }
                        }
                    })
                }
                up();
            }else{
                this.isMultiple = false;
                this.uploadOne(file).then(resolve).catch(reject);
            }
        }.bind(this))
    }
    uploadOne(file){
        var _this = this;
        return new Promise(function (resolve, reject){
            let params = ['filename=' + _this.random()].join('&');
            let xhr = _this.XMLHttpRequest();
            xhr.timeout = _this.timeout;
            xhr.onreadystatechange = function (){
                if(xhr.readyState === 4 && xhr.status === 200){
                    let res = eval("(" + xhr.responseText + ")");
                    if(!res || !res.success){
                        return xhr.onerror(res)
                    }
                    res = res ? res.data : {};
                    _this.key = res.key;
                    _this.ajax(res.host, _this.formatData({
                        key: _this.key,
                        policy: res.policy,
                        OSSAccessKeyId: res.accessid,
                        success_action_status: 200,
                        callback: res.callback,
                        signature: res.signature,
                        file: file,
                    })).then(resolve).catch(reject)
                }
            }
            xhr.ontimeout = reject;
            xhr.onerror = reject;
            xhr.onloadend = function (res){
                if(xhr.readyState !== 4 || xhr.status !== 200){
                    reject({
                        type: res.type,
                        message: res.target.statusText,
                        status: xhr.status,
                        url: res.target.responseURL
                    });
                }
            };

            xhr.open("GET", (_this.serverUrl + '?' + params ), true);
            xhr.withCredentials = false;
            xhr.crossDomain = true;
            xhr.setRequestHeader("x-xiao-token", "");
            xhr.send(null);
        }.bind(this))
    }
    format(file){
        let format = null;
        if(file.name && file.name.indexOf('.') >= 0){
            format = file.name.substr(file.name.indexOf('.') + 1)
        }
        if(!format && file.type){
            let arr = file.type.split('/');
            format = arr[1]
        }
        return format
    }
    ajax(url, formatData){
        let _this = this;
        return new Promise(function (resolve, reject){
            let xhr = _this.xhr = _this.XMLHttpRequest();
            xhr.timeout = _this.timeout;
            xhr.upload.onprogress = function (e){
                if(typeof _this.progress === 'function'){
                    if(_this.isMultiple){
                        Object.assign(_this.fileList[_this.fileIndex], {
                            fileIndex: _this.fileIndex,
                            progress: e.loaded / e.total * 100,
                            key: _this.key
                        })
                        _this.progress(_this.fileList)
                    }else{
                        _this.progress(e.loaded / e.total * 100)
                    }
                }
            }
            xhr.onreadystatechange = function (){
                if(xhr.readyState === 4 && xhr.status === 200){
                    let res = eval("(" + xhr.responseText + ")");
                    if(res && res.success){
                        resolve(res)
                        if(typeof _this.success === 'function'){
                            _this.success(_this.loadend)
                        }
                    }else{
                        reject(res);
                    }
                }
            }
            xhr.ontimeout = function (e){
                reject(e)
                if(typeof _this.timeout === 'function'){
                    _this.timeout(e)
                }
            };
            xhr.onloadend = function (res){
                if(xhr.readyState !== 4 || xhr.status !== 200){
                    reject({
                        type: res.type,
                        message: res.target.statusText,
                        status: xhr.status,
                        url: res.target.responseURL
                    });
                }
            };
            xhr.open("POST", url, true);
            xhr.withCredentials = false;
            xhr.crossDomain = true;
            xhr.setRequestHeader("x-xiao-token", "");
            xhr.send(formatData);
        })
    }
    formatData(obj){
        let formatdata = new FormData();
        for (let key in obj){
            formatdata.append(key, obj[key]);
        }
        return formatdata
    }
    stop(){       this.xhr && this.xhr.abort();}
    random(str){
        let date = new Date();
        return [
            date.getFullYear(),
            (date.getMonth() + 1),
            date.getDate(),
            date.getHours(),
            date.getMinutes(),
            date.getSeconds(),
            date.getMilliseconds(),
            (Math.random() * 10000000000000000000),
            str || ''
        ].join('')
    }
    addEventListener(type, fn){this[type] = fn;}
}
